<?php
namespace CRM\Util;
use Common\Util\HttpsConnection;
use Think\Db;
use Think\Log;

//向企业微信API发送请求，处理企业微信的回调的模型
class WXWork extends HttpsConnection{
    public $corpID;
    public $agentID;
    public $secret;
    public $domain;
    public $token;
    public $ticket;
    public $wxqy="https://qyapi.weixin.qq.com/cgi-bin/";
    function __construct(){
        $this->domain=C("Domain");
        $this->corpID=C("WXWork_CorpID");
        $this->agentID=C("WXWork_AgentId");
        $this->secret=C("WXWork_Secret");
    }
    protected function disposeResponse($content){
        $response=$this->parseData($content);
        if($response["errcode"]!==0){
            Log::record("response error:".var_export($response),Log::ERR);
            $this->error="response error";
            return false;
        }
        return $response;
    }
    public function getToken(){
        if($this->token){
            return $this->token;
        }
        $token=S("WXWorkToken");
        if(!$token){
            $url=$this->wxqy."gettoken?corpid=".$this->corpID."&corpsecret=".$this->secret;
            $response=$this->get($url);
            $token=$response["access_token"];
            S("WXWorkToken",$token,["expire"=>$response["expires_in"]]);
        }
        $this->token=$token;
        return $token;
    }
    public function getJSApiTicket(){
        if($this->ticket){
            return $this->ticket;
        }
        $ticket=S("WXWorkTicket");
        if(!$ticket){
            $url=$this->wxqy."get_jsapi_ticket?access_token=".$this->getToken();
            $response=$this->get($url);
            $ticket=$response["ticket"];
            S("WXWorkTicket",$ticket,["expire"=>$response["expires_in"]]);
        }
        $this->ticket=$ticket;
        return $ticket;
    }
    public function generateSignature(&$nonce,&$timestamp,&$url){
        $ticket=$this->getJSApiTicket();
        $nonce=rand(100000,999999);
        $timestamp=time();
        $url=$this->domain.$_SERVER['REQUEST_URI'];
        $string="jsapi_ticket=$ticket&noncestr=$nonce&timestamp=$timestamp&url=$url";
        $signature=sha1($string);
        // var_dump($ticket,$nonce,$timestamp,$url,$string,$signature);
        return $signature;
    }
    /**
     * 获取当前用户信息用的接口:getAuthUrl->getUserInfo->getUserDetail
     */
    //跳转到授权URL，获取授权后会跳转回来
    //授权级别:snsapi_base/snsapi_userinfo/snsapi_privateinfo
    public function getAuthUrl($redirect="",$scope="snsapi_userinfo",$params=""){
        if(!$redirect){
            $redirect=$this->getWholeUrl();
        }
        $query=[
            "appid"=>$this->corpID,
            "redirect_uri"=>$redirect,
            "response_type"=>"code",
            "scope"=>$scope,
            "agentid"=>$this->agentID,
            "state"=>json_encode($params),
            "rand"=>rand(0,999999)
        ];
        $url="https://open.weixin.qq.com/connect/oauth2/authorize?".http_build_query($query)."#wechat_redirect";
        return $url;
    }
    //获取包含域名在内的完整URL，用于从其他服务器跳转回来
    public function getWholeUrl($path=""){
        return $this->domain.U($path);
    }
    //通过授权的code获取当前用户的信息(userid,user_ticket之类的)
    //可能是企业成员(member)，也可能是外部成员(outside)
    public function getUserInfo($code){
        $url=$this->wxqy."user/getuserinfo?access_token=".$this->getToken()."&code=$code";
        $response=$this->get($url);
        if(!$response){
            return false;
        }
        $return=[];
        if($response["UserId"]){
            $return=[
                "type"=>"member",
                "userID"=>$response["UserId"],
                "deviceID"=>$response["DeviceId"]
            ];
        }
        else{
            $return=[
                "type"=>"outside",
                "openID"=>$response["OpenId"],
                "deviceID"=>$response["DeviceId"]
            ];
        }
        if($response["user_ticket"]){
            $return["user_ticket"]=$response["user_ticket"];
            $return["expires_in"]=$response["expires_in"];
        }
        return $return;
    }
    //获取用户信息(一般是非企业用户，企业用户有其他的接口可以用)
    public function getUserDetail($userTicket){
        $url=$this->wxqy."user/getuserdetail?access_token=".$this->getToken();
        $response=$this->post($url,["user_ticket"=>$userTicket]);
        if(!$response){
            return false;
        }
        return $response;
    }
    /**
     * 获取企业信息的接口
     */
    public function getDepartmentList($id=""){
        $url=$this->wxqy."department/list?access_token=".$this->getToken();
        if($id){
            $url.="&id=".$id;
        }
        $response=$this->get($url);
        if(!$response){
            return false;
        }
        return $response["department"];
    }
    public function getSimpleUserList($departmentID,$fetchChild=0){
        $url=$this->wxqy."user/simplelist?access_token=".$this->getToken()."&department_id=$departmentID&fetch_child=$fetchChild";
        $response=$this->get($url);
        return $response["userlist"];
    }
    public function getUserList($departmentID,$fetchChild=0){
        $url=$this->wxqy."user/list?access_token=".$this->getToken()."&department_id=$departmentID&fetch_child=$fetchChild";
        $response=$this->get($url);
        return $response["userlist"];
    }
    public function getUser($userID){
        $token=$this->getToken();
        $url="https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=$token&userid=$userID";
        $response=$this->get($url);
        return $response;
    }
    /**
     * 发送/接收消息
     */
    public function sendMessage(){
        $token=$this->getToken();
        $url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$token";
        $data=[
            "touser"=>"GuoDong",
            "msgtype"=>"text",
            "agentid"=>$this->agentID,
            "text"=>[
                "content"=>"测试消息"
            ]
        ];
        $this->post($url,$data);
    }
    /**
     * 其他功能
     */
    public function sync(){
        $token=$this->getToken();
        $db=Db::getInstance();

        $url=$this->wxqy."department/list?access_token=$token";
        $response=$this->get($url);
        if(!$response){
            return false;
        }
        $departmentList=$response["department"];
        $values=[];
        foreach($departmentList as $department){
            $values[]="(".$department["id"].",'".$department["name"]."',".$department["parentid"].",".$department["order"].")";
        }
        $sql="TRUNCATE `department`;";
        $sql.="INSERT INTO `department` (`id`, `name`, `parentid`, `order`) VALUES ".join(",",$values).";";
        
        $url=$this->wxqy."user/list?access_token=$token&department_id=1&fetch_child=1";
        $response=$this->get($url);
        if(!$response){
            return false;
        }
        $userList=$response["userlist"];
        $values=[];
        $user_department=[];
        foreach($userList as $user){
            $userID=$user["userid"];
            $values[]="('$userID', '".$user["name"]."', '".$user["mobile"]."', '".$user["position"]."', '".$user["gender"]."', '".$user["email"]."', '".$user["isleader"]."', '".$user["avatar"]."', '".$user["telephone"]."', '".$user["english_name"]."', '".$user["status"]."', '".$user["qr_code"]."')";
            foreach($user["department"] as $index=>$departmentID){
                $order=$user["order"][$index];
                $user_department[]="('$userID', '$departmentID', '$order')";
            }
        }
        $sql.="TRUNCATE `user`;";
        $sql.="INSERT INTO `user` (`userid`, `name`, `mobile`, `position`, `gender`, `email`, `isleader`, `avatar`, `telephone`, `english_name`, `status`, `qr_code`) VALUES ".join(",",$values).";";
        $sql.="TRUNCATE `user_department`;";
        $sql.="INSERT INTO `user_department` (`userid`, `department`, `order`) VALUES ".join(",",$user_department).";";

        $db->execute($sql);
        return true;
    }
    public function getUserDepartmentTree($id="1"){
        $department=D("Department");
        $view=D("UserDepartmentView");
        $root=$department->where(["id"=>$id])->find();
        $tree=$this->recursionUserDepartmentNode($department,$view,$root);
        return $tree;
    }
    private function recursionUserDepartmentNode($department,$view,$node){
        $id=$node["id"];
        $node["userList"]=$view->where(["department"=>$id])->select();
        $node["subList"]=[];
        $subList=$department->where(["parentid"=>$id])->select();
        foreach($subList as $sub){
            $node["subList"][]=$this->recursionUserDepartmentNode($department,$view,$sub);
        }
        return $node;
    }
}